package cn.hpclub.server.controller.h5.campus;

import java.util.Date;

import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.net.MediaType;

import cn.hpclub.server.constant.ClientApiConstant;
import cn.hpclub.server.constant.Constant;
import cn.hpclub.server.controller.h5.BaseH5Controller;
import cn.hpclub.server.model.campus.BroadbandOpenOrder;
import cn.hpclub.server.util.DateKit;
import cn.hpclub.server.util.HttpUtil;
import cn.hpclub.server.util.SystemConfigUtil;

public class BroadbandOpenOrderController extends BaseH5Controller{
    private String              REST_HOST_PREFIX = SystemConfigUtil.getSystemConfig().getRestHostPrefix();
    private static final Logger logger           = LoggerFactory.getLogger(BroadbandOpenOrderController.class);

    public void saveOrderToDzg(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);
        try{
            BroadbandOpenOrder order = getModel(BroadbandOpenOrder.class, "bd");
            order.set("created_time", new Date());
            order.save();

            int id = order.get("id");
            JSONObject uidObj = new JSONObject();
            uidObj.put("id", id);

            jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, "宽带开户订单提交成功", uidObj);

        }
        catch(Exception e){
            logger.error("异常：" + e.getMessage());
            jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, "宽带开户订单保存到大掌柜系统异常", ClientApiConstant.Msg.EMPTY);
        }
        finally{
            logger.debug("renderText:" + jo.toString());
            renderText(jo.toString());
        }
    }

    public void updateOrder(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);
        try{
            BroadbandOpenOrder order = getModel(BroadbandOpenOrder.class, "bd");
            order.set("last_updated_time", new Date());
            order.update();

            jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, "宽带开户订单更新成功", ClientApiConstant.Msg.EMPTY);

        }
        catch(Exception e){
            logger.error("异常：" + e.getMessage());
            jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, "宽带开户订单更新异常", ClientApiConstant.Msg.EMPTY);
        }
        finally{
            logger.debug("renderText:" + jo.toString());
            renderText(jo.toString());
        }
    }

    public void commitBdOrder(){
        JSONObject jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, ClientApiConstant.Msg.FAIL,
                                       ClientApiConstant.Msg.EMPTY);
        try{
            // 1. 获取H5页面参数，并保存到大掌柜系统
            int id = saveOrderToDzgLocal();

            String env = SystemConfigUtil.getSystemConfig().getEnvProfile();
            logger.debug("envProfile = " + env);
            if("prod".equals(env)){
                // 2. 提交订单到BOSS系统
                // String bossResult = saveDbOrderToBoss();
                String bossResult = saveDbOrder2Boss();
                // 3. 更新大掌柜系统订单
                updateOrderAtDzg(id, bossResult);
            }
            jo = setResponseObj(ClientApiConstant.ResultCode.SUCCESS_CODE, "宽带开户订单提交成功", ClientApiConstant.Msg.EMPTY);

        }
        catch(SaveBdOrderToDzgException e){
            logger.error("异常：" + e.getMessage());
            jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, e.getMessage(), ClientApiConstant.Msg.EMPTY);
        }
        catch(SaveBdOrderToBOSSException e){
            logger.error("异常：" + e.getMessage());
            jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, e.getMessage(), ClientApiConstant.Msg.EMPTY);
        }
        catch(SaveBdOrderToBOSSFail e){
            logger.error("异常：" + e.getMessage());
            jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, e.getMessage(), ClientApiConstant.Msg.EMPTY);
        }
        catch(Exception e){
            logger.error("异常：" + e.getMessage());
            jo = setResponseObj(ClientApiConstant.ResultCode.FAILED, "宽带开户订单提交异常", ClientApiConstant.Msg.EMPTY);
        }
        finally{
            logger.debug("renderText:" + jo.toString());
            renderText(jo.toString());
        }
    }

    private void updateOrderAtDzg(int id, String bossResult) throws SaveBdOrderToBOSSException, SaveBdOrderToBOSSFail{
        BroadbandOpenOrder updateBdOrder = new BroadbandOpenOrder();

        try{
            updateBdOrder.set("id", id);
            updateBdOrder.set("boss_return_result",
                              bossResult.substring(0, (bossResult.length() > 1000) ? 1000 : bossResult.length()));

            JSONObject data = new JSONObject(bossResult);
            JSONObject root = data.getJSONObject("ROOT");
            int resCode = root.getInt("RETURN_CODE");

            // 查询到有数据的情况
            if(resCode == 0){
                JSONObject outData = root.getJSONObject("OUT_DATA");
                Object order_id = outData.get("ORDER_ID");
                Object create_accept = outData.get("CREATE_ACCEPT");
                Object id_no = outData.get("ID_NO");
                Object phone_no = outData.get("PHONE_NO");
                Object master_serv_id = outData.get("MASTER_SERV_ID");

                updateBdOrder.set("order_id", order_id);
                updateBdOrder.set("create_accept", create_accept);
                updateBdOrder.set("id_no", id_no);
                updateBdOrder.set("phone_no", phone_no);
                updateBdOrder.set("master_serv_id", master_serv_id);
                updateBdOrder.set("order_status", 10);
                updateBdOrder.set("last_updated_time", new Date());

                updateBdOrder.update();

            }else{
                updateBdOrder.set("order_status", 15);
                updateBdOrder.set("last_updated_time", new Date());
                updateBdOrder.update();

                String resMsg = root.getString("RETURN_MSG");
                if(root.has("DETAIL_MSG")){
                    resMsg = root.getString("DETAIL_MSG");
                } else if(root.has("USER_MSG")){
                    resMsg = root.getString("USER_MSG");
                }
                if(resCode == 1005){
                    if(bossResult.contains("timed out")
                            || bossResult.contains("CRM_TEMPLATE")
                            || bossResult.contains("中间件") || bossResult.contains("系统忙")){
                        resMsg = "调用服务超时，请核实是否办理成功。";
                    }
                }

                throw new SaveBdOrderToBOSSFail(resMsg);
            }

        }
        catch(JSONException e){
            updateBdOrder.set("order_status", 20);
            updateBdOrder.set("last_updated_time", new Date());
            updateBdOrder.update();

            throw new SaveBdOrderToBOSSException("BOSS系统返回数据解析异常");
        }
    }

    private String saveDbOrder2Boss() throws SaveBdOrderToBOSSException{
        String url = REST_HOST_PREFIX + Constant.RestUrl.BROAD_BAND_OPEN;
        logger.info("recharge interface in.url = " + url);
        String result = "";
        try{
            // 本地编码
            String body = getOpenBroadBandRequestBody();
            result = HttpUtil.syncPostJsonBody(url, MediaType.JSON_UTF_8, body, 30000);
            return result;
        }
        catch(Exception e){
            throw new SaveBdOrderToBOSSException("宽带开户订单保存到BOSS系统失败");
        }
    }

    private String getOpenBroadBandRequestBody(){
        JSONObject root = new JSONObject();
        root.put("HEADER", getHeader());
        root.put("BODY", getBody());
        return root.toString();
    }

    private JSONObject getHeader(){
        JSONObject header = new JSONObject();
        header.put("ROUTE_PHONE_NO", getPara("empPhonbe"));
        return header;
    }

    private JSONObject getBody(){
        JSONObject body = new JSONObject();
        body.put("LOGIN_NO", getPara("bd.login_no"));
        body.put("GROUP_ID", getPara("bd.group_id"));
        body.put("REGION_ID", getPara("bd.region_id"));
        body.put("OP_CODE", "1093");
        body.put("CUST_FLAG", "2");
        body.put("OP_NOTE", "");
        body.put("VERIFY_FLAG", "0");
        body.put("CHN_CODE", "99");
        body.put("ID_ICCID", getPara("bd.id_iccid"));
        body.put("ID_TYPE", "1");
        body.put("SEX_CODE", "");
        body.put("CUST_ID", getPara("bd.cust_id"));
        body.put("CUST_NAME", getPara("bd.cust_name"));
        body.put("CUST_ADDRESS", getPara("bd.cust_address"));
        body.put("ID_ADDRESS", getPara("bd.id_address"));
        body.put("ID_VALIDDATE", getPara("bd.id_validdate"));
        body.put("TYPE_CODE", "1");
        body.put("PHONE_NO", "");
        body.put("USERGROUP_FLAG", "3");
        body.put("USER_GROUP", getPara("bd.user_group"));
        body.put("PROD_ID", getPara("bd.prod_id"));
        body.put("IP_ADDR", "");
        body.put("PRE_ACCEPT", "");
        body.put("PRE_LOGIN_NO", "");
        body.put("DIRECT_STATE", "");
        body.put("SWDL_FLAG", "");
        body.put("ADD_PRODUCT_LIST", getPara("bd.add_product_list"));
        body.put("CHNN_ID", "96");
        body.put("FEE_INFO", getFeeInfo());
        body.put("KD_INFO", getKdInfo());
        body.put("PRODUCT_LIST", getProductList());

        return body;
    }

    private JSONObject getProductList(){
        JSONObject product = new JSONObject();
        product.put("PROD_ID", getPara("bd.prod_id"));
        product.put("EFF_DATE", DateKit.toStr(new Date(), "yyyyMMddHHmmss"));
        product.put("EXP_DATE", "");

        JSONObject productInfo = new JSONObject();
        productInfo.put("PROD_PRCID", getPara("bd.prod_prcid"));
        productInfo.put("PRODPRCATTR_LIST", new JSONObject());
        productInfo.put("SVCATTR_LIST", new JSONObject());

        JSONObject prodPrc = new JSONObject();
        prodPrc.put("DEVELOP_NO", getPara("bd.login_no"));
        productInfo.put("PRODPRC", prodPrc);

        product.put("PRODPRC_INFO", productInfo);

        JSONObject productList = new JSONObject();
        productList.put("PRODUCT", product);
        return productList;
    }

    private JSONObject getFeeInfo(){
        JSONObject feeInfo = new JSONObject();
        feeInfo.put("PREPAY_FEE", getPara("bd.prepay_fee"));
        feeInfo.put("ENTER_FEE", getPara("bd.enter_fee"));
        feeInfo.put("MA_FEE", getPara("bd.ma_fee"));
        return feeInfo;
    }

    private JSONObject getKdInfo(){
        JSONObject kdInfo = new JSONObject();
        kdInfo.put("CON_PHONE", getPara("bd.con_phone"));
        kdInfo.put("CFM_LOGIN", getPara("bd.cfm_login"));
        kdInfo.put("TIMER", "");
        kdInfo.put("USER_PASSWD", getPara("bd.user_passwd"));
        kdInfo.put("DOMAINS", getPara("bd.domains"));
        kdInfo.put("ENTER_NUM", getPara("bd.enter_num"));
        kdInfo.put("ADD_INTER_MODE", getPara("bd.add_inter_mode"));
        kdInfo.put("BAND_WIDTH", getPara("bd.band_width"));
        kdInfo.put("CONTRACT_NO_2", getPara("bd.contract_no_2"));
        kdInfo.put("TAX_NUM", "");
        kdInfo.put("ADDRESS_ID", getPara("bd.address_id"));
        kdInfo.put("ADDRESS", getPara("bd.address"));
        kdInfo.put("BUILD_ADDR_ID", getPara("bd.build_addr_id"));
        kdInfo.put("ADD_COOP_MODE", getPara("bd.add_coop_mode"));
        kdInfo.put("ADD_EXPAND_ADDR", getPara("bd.add_expand_addr"));
        kdInfo.put("WORK_FLAG", "0");
        kdInfo.put("AREA_NAME", getPara("bd.area_name"));
        return kdInfo;
    }

    private int saveOrderToDzgLocal() throws SaveBdOrderToDzgException{
        int uid = 0;
        try{
            BroadbandOpenOrder order = getModel(BroadbandOpenOrder.class, "bd");
            // 中文重新赋值
            // order.set("area_name",
            // URLDecoder.decode(order.get("area_name")));
            // 订单初始状态
            order.set("order_status", 5);
            // 创建时间
            order.set("created_time", new Date());

            order.save();
            // 主键ID
            uid = order.get("id");
        }
        catch(Exception e){
            throw new SaveBdOrderToDzgException("宽带开户订单保存到大掌柜失败");
        }

        return uid;
    }

    public static class SaveBdOrderToDzgException extends Exception{
        private static final long serialVersionUID = 6089557738298976818L;

        public SaveBdOrderToDzgException(String message){
            super(message);
        }
    }

    public static class SaveBdOrderToBOSSException extends Exception{
        private static final long serialVersionUID = 8089556668298971818L;

        public SaveBdOrderToBOSSException(String message){
            super(message);
        }
    }

    public static class SaveBdOrderToBOSSFail extends Exception{
        private static final long serialVersionUID = 1234556565558971818L;

        public SaveBdOrderToBOSSFail(String message){
            super(message);
        }
    }
}
